/**
 * 加密工具统一导出
 * 
 * @author RickPan Team
 * @version 1.0
 * @since 2025-07-19
 */

// 导出核心类
export { MessageEncryption } from './MessageEncryption'
export { KeyManager } from './KeyManager'

// 导出枚举（作为值导出）
export { EncryptionStatus, EncryptionErrorType } from '@/types/encryption'

// 导出类型（从统一的类型定义文件）
export type {
  EncryptedMessage,
  DecryptedMessage,
  TeamKeyInfo,
  KeyCacheEntry
} from '@/types/encryption'

export type {
  EncryptionConfig,
  EncryptionError,
  EncryptionHealthStatus,
  KeyCacheStats,
  EncryptedTeamMessage,
  SendMessageRequest,
  EncryptionPerformanceResult,
  BatchEncryptRequest,
  BatchEncryptResponse,
  BatchDecryptRequest,
  BatchDecryptResponse
} from '@/types/encryption'

/**
 * 加密工具函数集合
 */
export class EncryptionUtils {
  /**
   * 验证加密数据的完整性
   */
  static validateEncryptedData(data: any): boolean {
    return !!(
      data &&
      typeof data.ciphertext === 'string' &&
      typeof data.iv === 'string' &&
      typeof data.algorithm === 'string' &&
      data.algorithm === 'AES-256-GCM'
    )
  }

  /**
   * 生成任务ID
   */
  static generateTaskId(prefix: string = 'task'): string {
    return `${prefix}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
  }

  /**
   * 格式化文件大小
   */
  static formatFileSize(bytes: number): string {
    if (bytes === 0) return '0 B'
    
    const k = 1024
    const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
    const i = Math.floor(Math.log(bytes) / Math.log(k))
    
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
  }

  /**
   * 格式化时间间隔
   */
  static formatDuration(milliseconds: number): string {
    if (milliseconds < 1000) {
      return `${milliseconds.toFixed(2)}ms`
    } else if (milliseconds < 60000) {
      return `${(milliseconds / 1000).toFixed(2)}s`
    } else {
      return `${(milliseconds / 60000).toFixed(2)}min`
    }
  }

  /**
   * 检查是否为加密消息
   */
  static isEncryptedMessage(message: any): boolean {
    return !!(
      message &&
      message.isEncrypted === true &&
      message.iv &&
      message.encryptionAlgorithm
    )
  }

  /**
   * 创建加密错误对象
   */
  static createEncryptionError(
    type: EncryptionErrorType,
    message: string,
    teamId?: number,
    originalError?: Error
  ): EncryptionError {
    const error = new Error(message) as EncryptionError
    error.type = type
    error.teamId = teamId
    error.originalError = originalError
    error.timestamp = Date.now()
    return error
  }

  /**
   * 安全地清理敏感数据
   */
  static secureClear(obj: any): void {
    if (typeof obj === 'object' && obj !== null) {
      for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
          if (typeof obj[key] === 'string') {
            // 用随机字符覆盖字符串
            obj[key] = Array(obj[key].length).fill(0).map(() => 
              String.fromCharCode(Math.floor(Math.random() * 256))
            ).join('')
          }
          delete obj[key]
        }
      }
    }
  }

  /**
   * 计算字符串的哈希值（用于搜索索引）
   */
  static async calculateHash(text: string): Promise<string> {
    if (!window.crypto || !window.crypto.subtle) {
      // 降级到简单哈希
      let hash = 0
      for (let i = 0; i < text.length; i++) {
        const char = text.charCodeAt(i)
        hash = ((hash << 5) - hash) + char
        hash = hash & hash // 转换为32位整数
      }
      return Math.abs(hash).toString(36)
    }

    const encoder = new TextEncoder()
    const data = encoder.encode(text)
    const hashBuffer = await window.crypto.subtle.digest('SHA-256', data)
    const hashArray = Array.from(new Uint8Array(hashBuffer))
    return hashArray.map(b => b.toString(16).padStart(2, '0')).join('')
  }

  /**
   * 生成搜索关键词的哈希索引
   */
  static async generateSearchIndex(content: string): Promise<string[]> {
    const words = content.toLowerCase()
      .replace(/[^\w\s\u4e00-\u9fff]/g, ' ') // 保留中英文字符
      .split(/\s+/)
      .filter(word => word.length > 1) // 过滤单字符

    const hashes = await Promise.all(
      words.map(word => this.calculateHash(word))
    )

    return [...new Set(hashes)] // 去重
  }

  /**
   * 验证密钥强度
   */
  static validateKeyStrength(keyBase64: string): {
    isValid: boolean
    strength: 'weak' | 'medium' | 'strong'
    issues: string[]
  } {
    const issues: string[] = []
    
    try {
      const keyBuffer = atob(keyBase64)
      
      if (keyBuffer.length < 32) {
        issues.push('密钥长度不足256位')
      }

      // 检查熵
      const bytes = new Uint8Array(keyBuffer.length)
      for (let i = 0; i < keyBuffer.length; i++) {
        bytes[i] = keyBuffer.charCodeAt(i)
      }

      const entropy = this.calculateEntropy(bytes)
      if (entropy < 7.5) {
        issues.push('密钥熵值过低')
      }

      let strength: 'weak' | 'medium' | 'strong' = 'strong'
      if (issues.length > 1) {
        strength = 'weak'
      } else if (issues.length === 1) {
        strength = 'medium'
      }

      return {
        isValid: issues.length === 0,
        strength,
        issues
      }

    } catch (error) {
      return {
        isValid: false,
        strength: 'weak',
        issues: ['密钥格式无效']
      }
    }
  }

  /**
   * 计算字节数组的熵值
   */
  private static calculateEntropy(bytes: Uint8Array): number {
    const frequency = new Array(256).fill(0)
    
    for (const byte of bytes) {
      frequency[byte]++
    }

    let entropy = 0
    const length = bytes.length

    for (const count of frequency) {
      if (count > 0) {
        const probability = count / length
        entropy -= probability * Math.log2(probability)
      }
    }

    return entropy
  }

  /**
   * 创建性能监控器
   */
  static createPerformanceMonitor() {
    const metrics = {
      encryptionTimes: [] as number[],
      decryptionTimes: [] as number[],
      keyFetchTimes: [] as number[]
    }

    return {
      startTimer: () => performance.now(),
      
      recordEncryption: (startTime: number) => {
        const duration = performance.now() - startTime
        metrics.encryptionTimes.push(duration)
        if (metrics.encryptionTimes.length > 100) {
          metrics.encryptionTimes.shift()
        }
      },

      recordDecryption: (startTime: number) => {
        const duration = performance.now() - startTime
        metrics.decryptionTimes.push(duration)
        if (metrics.decryptionTimes.length > 100) {
          metrics.decryptionTimes.shift()
        }
      },

      recordKeyFetch: (startTime: number) => {
        const duration = performance.now() - startTime
        metrics.keyFetchTimes.push(duration)
        if (metrics.keyFetchTimes.length > 100) {
          metrics.keyFetchTimes.shift()
        }
      },

      getStats: () => ({
        avgEncryptionTime: metrics.encryptionTimes.length > 0 
          ? metrics.encryptionTimes.reduce((a, b) => a + b, 0) / metrics.encryptionTimes.length 
          : 0,
        avgDecryptionTime: metrics.decryptionTimes.length > 0 
          ? metrics.decryptionTimes.reduce((a, b) => a + b, 0) / metrics.decryptionTimes.length 
          : 0,
        avgKeyFetchTime: metrics.keyFetchTimes.length > 0 
          ? metrics.keyFetchTimes.reduce((a, b) => a + b, 0) / metrics.keyFetchTimes.length 
          : 0,
        totalOperations: metrics.encryptionTimes.length + metrics.decryptionTimes.length
      }),

      reset: () => {
        metrics.encryptionTimes = []
        metrics.decryptionTimes = []
        metrics.keyFetchTimes = []
      }
    }
  }

  /**
   * 检测浏览器加密性能
   */
  static async benchmarkEncryption(): Promise<{
    encryptionsPerSecond: number
    decryptionsPerSecond: number
    avgEncryptionTime: number
    avgDecryptionTime: number
  }> {
    if (!MessageEncryption.isSupported()) {
      throw new Error('浏览器不支持Web Crypto API')
    }

    const testKey = await MessageEncryption.generateTestKey()
    const testData = 'This is a test message for encryption benchmarking.'
    const iterations = 50

    // 预热
    for (let i = 0; i < 5; i++) {
      const encrypted = await MessageEncryption.encryptMessage(testData, testKey)
      await MessageEncryption.decryptMessage(encrypted, testKey)
    }

    // 测试加密性能
    const encryptStart = performance.now()
    const encryptedMessages = []
    for (let i = 0; i < iterations; i++) {
      encryptedMessages.push(await MessageEncryption.encryptMessage(testData, testKey))
    }
    const encryptEnd = performance.now()

    // 测试解密性能
    const decryptStart = performance.now()
    for (const encrypted of encryptedMessages) {
      await MessageEncryption.decryptMessage(encrypted, testKey)
    }
    const decryptEnd = performance.now()

    const encryptTime = encryptEnd - encryptStart
    const decryptTime = decryptEnd - decryptStart

    return {
      encryptionsPerSecond: Math.round((iterations * 1000) / encryptTime),
      decryptionsPerSecond: Math.round((iterations * 1000) / decryptTime),
      avgEncryptionTime: encryptTime / iterations,
      avgDecryptionTime: decryptTime / iterations
    }
  }
}
